package org.dtrd.config.wechat.api.impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;
import org.dtrd.config.wechat.api.IWechatPayApi;
import org.dtrd.config.wechat.api.IWechatPayApi.WechatPaySystemApi.GetRequest;
import org.dtrd.config.wechat.api.IWechatPayApi.WechatPaySystemApi.PostRequest;
import org.dtrd.config.wechat.config.wechatpay.PayScene;
import org.dtrd.config.wechat.entity.request.wechatpay.*;
import org.springframework.stereotype.Component;

/**
 * 微信支付相关
 *
 * @author xiao
 * @date 2022/3/18 9:43 PM
 */
@Component
@Slf4j
public class WechatPayApi implements IWechatPayApi {

    @Override
    public String h5PrePay(Long total, Integer userId, String outTradeNo, String description, String attach, SceneInfo sceneInfo) {
        ObjectNode request = buildRequest(total, userId, outTradeNo, description, attach);
        request.putObject("scene_info")
                .put("payer_client_ip", sceneInfo.getPayer_client_ip())
                .put("device_ip", sceneInfo.getDevice_ip());
        H5Info h5Info = sceneInfo.getH5_info();
        if (h5Info != null) {
            request.putObject("h5_info")
                    .put("type", h5Info.getType())
                    .put("app_name", h5Info.getApp_name())
                    .put("app_url", h5Info.getApp_url())
                    .put("bundle_id", h5Info.getBundle_id())
                    .put("package_name", h5Info.getPackage_name());
        }
        log.info("WechatPayApi.h5PrePay.[total, userId, outTradeNo, description, appId, attach, sceneInfo] request = " + request + "; " + JSONObject.toJSONString(request) + "; JSONUtil.toJsonStr= " + JSONUtil.toJsonStr(request));
        return prePay(PayScene.H5, request);
    }

    @Override
    public String appPrePay(Long total, Integer userId, String outTradeNo, String description, String attach) {
        ObjectNode request = buildRequest(total, userId, outTradeNo, description, attach);
        return prePay(PayScene.APP, request);
    }

    @Override
    public String jsPrePay(Long total, Integer userId, String openId, String outTradeNo, String description, String attach) {
        ObjectNode request = buildRequest(total, userId, outTradeNo, description, attach);
        request.putObject("payer")
                .put("openid", openId);
        return prePay(PayScene.JSAPI, request);
    }

    @Override
    public String nativePrePay(Long total, Integer userId, String outTradeNo, String description, String attach, SceneInfo sceneInfo) {
        ObjectNode request = buildRequest(total, userId, outTradeNo, description, attach);
        request.putObject("scene_info")
                .put("payer_client_ip", sceneInfo.getPayer_client_ip())
                .put("device_ip", sceneInfo.getDevice_ip());
        StoreInfo storeInfo = sceneInfo.getStore_info();
        if (storeInfo != null) {
            request.putObject("store_info")
                    .put("id", storeInfo.getId())
                    .put("name", storeInfo.getName())
                    .put("area_code", storeInfo.getArea_code())
                    .put("address", storeInfo.getAddress());
        }
        return prePay(PayScene.NATIVE, request);
    }

    @Override
    public String queryOrderByWechatPayNo(String wechatPayNo) {
        return getRequest(GetRequest.QUERY_ORDER_WECHATPAY_NO + wechatPayNo, null);
    }

    @Override
    public String queryOrderBySystemOrderNo(String systemOrderNo) {
        return getRequest(GetRequest.QUERY_ORDER_SYSTEM_NO + systemOrderNo, null);
    }

    @Override
    public String closeOrder(String orderNo) {
        String url = PostRequest.CLOSE_ORDER + orderNo + "/close";
        ObjectNode rootNode = new ObjectMapper().createObjectNode();
        return postRequest(url, rootNode);
    }

}
